﻿/*  
 * Helix Engine
 * http://helixengine.codeplex.com/
 * 
 * Copyright (c) 2010 - 2011 Joe Hegarty
 *  
 * This source code is subject to the terms of the Microsoft Public License (Ms-PL). 
 *  
 * Redistribution and use in source and binary forms, with or without modification, 
 * is permitted provided that redistributions of the source code retain the above 
 * copyright notices and this file header. 
 * 
 * For details please see http://www.opensource.org/licenses/ms-pl.html 
 *  
 * All other rights reserved. 
 *
 */  


using System;
using System.Collections.Generic;

using HelixEngine.Exceptions;

namespace HelixEngine.Resources
{

    /// <remarks>
    /// Represents the resources subsystem of the engine
    /// </remarks>
    public sealed class ResourceManager
    {
        Dictionary<string, ResourcePackage> _packageMap = new Dictionary<string, ResourcePackage>();

        /// <summary>
        /// Checks if a package has already been requested and is known to the resource manager
        /// </summary>
        /// <param name="package">The package to check exists</param>
        /// <returns>True when the package is already known</returns>
        public bool IsPackageKnown(string package)
        {
            return _packageMap.ContainsKey(package);
        }

        /// <summary>
        /// Check if a package has already been successfully cache
        /// </summary>
        /// <param name="package">The package to check is cached</param>
        /// <returns>True when the package is already cached</returns>
        public bool IsPackageCached(string package)
        {
            ResourcePackage resourcePackage = null;
            if (_packageMap.TryGetValue(package, out resourcePackage))
            {
                return resourcePackage.IsComplete;
            }

            return false;
        }

        /// <summary>
        /// Gets the progress of a package download
        /// </summary>
        /// <param name="package">The package to get the progress of</param>
        /// <returns>The percentage of download progess</returns>
        public int GetPackageProgress(string package)
        {
            ResourcePackage resourcePackage = null;
            if (_packageMap.TryGetValue(package, out resourcePackage))
            {
                return resourcePackage.DownloadProgress;
            }

            return 0;
        }

        /// <summary>
        /// Tries to get a package
        /// </summary>
        /// <param name="package">The package to try and get</param>
        /// <param name="resourcePackage">The resource package to assign the result to if successful</param>
        /// <returns>True when resourcePackage was successfully set</returns>
        public bool TryGetPackage(string package, out ResourcePackage resourcePackage)
        {
            if (_packageMap.TryGetValue(package, out resourcePackage))
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Gets a package from the resource manager
        /// </summary>
        /// <param name="package">The package to get</param>
        /// <exception cref="PackageNotKnownException">
        /// Thrown when the package does is not known to the resource manager
        /// </exception>
        /// <returns>The package requested</returns>
        public ResourcePackage GetPackage(string package)
        {
            ResourcePackage resourcePackage = null;
            if (_packageMap.TryGetValue(package, out resourcePackage))
            {
                return resourcePackage;
            }

            throw new PackageNotKnownException(package);
        }

        /// <summary>
        /// Adds a package to be fetched. If the package is already known, does nothing.
        /// </summary>
        /// <param name="package">The package to fetch</param>
        /// <returns>The created or existing package</returns>
        public ResourcePackage FetchPackage(string package)
        {
            ResourcePackage resourcePackage = null;
            if (!TryGetPackage(package, out resourcePackage))
            {
                resourcePackage = new ResourcePackage(package);
                _packageMap.Add(package, resourcePackage);
            }

            return resourcePackage;
        }
    }
}
